﻿/*
 * 作者：新生命开发团队（http://www.newlifex.com/）
 * 
 * 版权：版权所有 (C) 新生命开发团队 2002-2014
 * 
 * 修改：海洋饼干（cuteant@outlook.com）
*/

using System;
using System.ComponentModel;
using CuteAnt.Configuration;

namespace CuteAnt.Log
{
	/// <summary>日志基类。提供日志的基本实现</summary>
	[EditorBrowsable(EditorBrowsableState.Advanced)]
	public abstract class Logger : ILog
	{
		#region -- 主方法 --

		#region - Debug -

		/// <summary>调试日志</summary>
		/// <param name="msg">调试信息</param>
		public virtual void Debug(String msg)
		{
			Write(LogLevel.Debug, msg);
		}

		/// <summary>调试日志</summary>
		/// <param name="format">格式化字符串</param>
		/// <param name="args">格式化参数</param>
		public virtual void Debug(String format, params Object[] args)
		{
			Write(LogLevel.Debug, format, args);
		}

		#endregion

		#region - Info -

		/// <summary>信息日志</summary>
		/// <param name="msg">信息</param>
		public virtual void Info(String msg)
		{
			Write(LogLevel.Info, msg);
		}

		/// <summary>信息日志</summary>
		/// <param name="format">格式化字符串</param>
		/// <param name="args">格式化参数</param>
		public virtual void Info(String format, params Object[] args)
		{
			Write(LogLevel.Info, format, args);
		}

		#endregion

		#region - Warn -

		/// <summary>警告日志</summary>
		/// <param name="msg">警告信息</param>
		public virtual void Warn(String msg)
		{
			Write(LogLevel.Warn, msg);
		}

		/// <summary>警告日志</summary>
		/// <param name="format">格式化字符串</param>
		/// <param name="args">格式化参数</param>
		public virtual void Warn(String format, params Object[] args)
		{
			Write(LogLevel.Warn, format, args);
		}

		#endregion

		#region - Error -

		/// <summary>错误日志</summary>
		/// <param name="msg">错误信息</param>
		public virtual void Error(String msg)
		{
			Write(LogLevel.Error, msg);
		}

		/// <summary>错误日志</summary>
		/// <param name="formatMsg">格式化字符串</param>
		/// <param name="args">格式化参数</param>
		public virtual void Error(String formatMsg, params Object[] args)
		{
			Write(LogLevel.Error, formatMsg, args);
		}

		/// <summary>错误日志</summary>
		/// <param name="ex">异常</param>
		public virtual void Error(Exception ex)
		{
			Write(LogLevel.Error, ex);
		}

		/// <summary>错误日志</summary>
		/// <param name="ex">异常</param>
		/// <param name="msg">信息</param>
		public virtual void Error(Exception ex, String msg)
		{
			Write(LogLevel.Error, ex, msg);
		}

		/// <summary>错误日志</summary>
		/// <param name="ex">异常</param>
		/// <param name="formatMsg">格式化字符串</param>
		/// <param name="args">格式化参数</param>
		public virtual void Error(Exception ex, String formatMsg, params Object[] args)
		{
			Write(LogLevel.Error, ex, formatMsg, args);
		}

		#endregion

		#region - Fatal -

		/// <summary>严重错误日志</summary>
		/// <param name="msg">错误信息</param>
		public virtual void Fatal(String msg)
		{
			Write(LogLevel.Fatal, msg);
		}

		/// <summary>严重错误日志</summary>
		/// <param name="format">格式化字符串</param>
		/// <param name="args">格式化参数</param>
		public virtual void Fatal(String format, params Object[] args)
		{
			Write(LogLevel.Fatal, format, args);
		}

		/// <summary>严重错误日志</summary>
		/// <param name="ex">异常</param>
		public virtual void Fatal(Exception ex)
		{
			Write(LogLevel.Fatal, ex);
		}

		/// <summary>严重错误日志</summary>
		/// <param name="ex">异常</param>
		/// <param name="msg">信息</param>
		public virtual void Fatal(Exception ex, String msg)
		{
			Write(LogLevel.Fatal, ex, msg);
		}

		/// <summary>严重错误日志</summary>
		/// <param name="ex">异常</param>
		/// <param name="formatMsg">格式化字符串</param>
		/// <param name="args">格式化参数</param>
		public virtual void Fatal(Exception ex, String formatMsg, params Object[] args)
		{
			Write(LogLevel.Fatal, ex, formatMsg, args);
		}

		#endregion

		#endregion

		#region -- 核心方法 --

		/// <summary>写日志</summary>
		/// <param name="level">日志级别</param>
		/// <param name="msg">信息</param>
		public virtual void Write(LogLevel level, String msg)
		{
			if (level >= Level) { OnWrite(level, msg); }
		}

		/// <summary>写日志</summary>
		/// <param name="level">日志级别</param>
		/// <param name="msg">信息</param>
		protected virtual void OnWrite(LogLevel level, String msg)
		{
			OnWrite(level, null, msg, null);
		}

		/// <summary>写带格式信息的日志</summary>
		/// <param name="level">日志级别</param>
		/// <param name="formatMsg">格式化字符串</param>
		/// <param name="args">格式化参数</param>
		public virtual void Write(LogLevel level, String formatMsg, params Object[] args)
		{
			if (level >= Level) { OnWrite(level, formatMsg, args); }
		}

		/// <summary>写带格式信息的日志</summary>
		/// <param name="level">日志级别</param>
		/// <param name="formatMsg">格式化字符串</param>
		/// <param name="args">格式化参数</param>
		protected virtual void OnWrite(LogLevel level, String formatMsg, params Object[] args)
		{
			OnWrite(level, null, formatMsg, args);
		}

		/// <summary>写异常日志</summary>
		/// <param name="level">日志级别</param>
		/// <param name="ex">异常</param>
		public virtual void Write(LogLevel level, Exception ex)
		{
			if (level >= Level) { OnWrite(level, ex); }
		}

		/// <summary>写异常日志</summary>
		/// <param name="level">日志级别</param>
		/// <param name="ex">异常</param>
		protected virtual void OnWrite(LogLevel level, Exception ex)
		{
			OnWrite(level, ex, null, null);
		}

		/// <summary>写异常日志</summary>
		/// <param name="level">日志级别</param>
		/// <param name="ex">异常</param>
		/// <param name="msg">信息</param>
		public virtual void Write(LogLevel level, Exception ex, String msg)
		{
			if (level >= Level) { OnWrite(level, ex, msg); }
		}

		/// <summary>写异常日志</summary>
		/// <param name="level">日志级别</param>
		/// <param name="ex">异常</param>
		/// <param name="msg">信息</param>
		protected virtual void OnWrite(LogLevel level, Exception ex, String msg)
		{
			OnWrite(level, ex, msg, null);
		}

		/// <summary>写带格式信息的异常日志</summary>
		/// <param name="level">日志级别</param>
		/// <param name="ex">异常</param>
		/// <param name="formatMsg">格式化字符串</param>
		/// <param name="args">格式化参数</param>
		public virtual void Write(LogLevel level, Exception ex, String formatMsg, params Object[] args)
		{
			if (level >= Level) { OnWrite(level, ex, formatMsg, args); }
		}

		/// <summary>写带格式信息的异常日志</summary>
		/// <param name="level">日志级别</param>
		/// <param name="ex">异常</param>
		/// <param name="formatMsg">格式化字符串</param>
		/// <param name="args">格式化参数</param>
		protected abstract void OnWrite(LogLevel level, Exception ex, String formatMsg, params Object[] args);

		#endregion

		#region -- 辅助方法 --

		/// <summary>格式化参数，特殊处理异常和时间</summary>
		/// <param name="format"></param>
		/// <param name="args"></param>
		/// <returns></returns>
		protected virtual String Format(String format, Object[] args)
		{
			if (args == null || args.Length < 1) { return format; }

			//处理时间的格式化
			//if (args != null && args.Length > 0)
			//{
			// 特殊处理异常
			if (args.Length == 1 && args[0] is Exception && (format.IsNullOrWhiteSpace() || format == "{0}"))
			{
				return "" + args[0];
			}

			for (var i = 0; i < args.Length; i++)
			{
				if (args[i] != null && args[i].GetType() == typeof(DateTime))
				{
					// 根据时间值的精确度选择不同的格式化输出
					var dt = (DateTime)args[i];
					if (dt.Millisecond > 0)
					{
						args[i] = dt.ToString("yyyy-MM-dd HH:mm:ss.fff");
					}
					else if (dt.Hour > 0 || dt.Minute > 0 || dt.Second > 0)
					{
						args[i] = dt.ToString("yyyy-MM-dd HH:mm:ss");
					}
					else
					{
						args[i] = dt.ToString("yyyy-MM-dd");
					}
				}
			}
			//}

			return String.Format(format, args);
		}

		#endregion

		#region -- 属性 --

		private LogLevel _Level = LogLevel.All;
		//private LogLevel? _Level;

		/// <summary>日志等级，只输出大于等于该级别的日志</summary>
		public LogLevel Level
		{
			//get
			//{
			//	if (_Level != null) return _Level.Value;

			//	try
			//	{
			//		var def = LogLevel.Info;
			//		if (Config.GetConfig<Boolean>("NewLife.Debug")) def = LogLevel.Debug;

			//		return Config.GetConfig<LogLevel>("NewLife.LogLevel", def);
			//	}
			//	catch { return LogLevel.Info; }
			//}
			get { return _Level; }
			set { _Level = value; }
		}

		#endregion

		#region -- 静态空实现 --

		private static ILog _Null = new NullLogger();

		/// <summary>空日志实现</summary>
		public static ILog Null { get { return _Null; } }

		internal class NullLogger : Logger
		{
			/// <summary>写带格式信息的异常日志</summary>
			/// <param name="level">日志级别</param>
			/// <param name="ex">异常</param>
			/// <param name="formatMsg">格式化字符串</param>
			/// <param name="args">格式化参数</param>
			protected override void OnWrite(LogLevel level, Exception ex, String formatMsg, params Object[] args) { }
		}

		#endregion
	}
}